// Copyright (c) 2019 Presto Labs Pte. Ltd.
// Author: xguo

#include <gtest/gtest.h>
#include <toml.hpp>

#include "coin2/base/time.h"
#include "coin2/exchange/base/market/enums.h"
#include "coin2/exchange/factory/symbology/product.h"

using namespace coin::proto;
using coin2::exchange::base::market::MarketType;

TEST(IProduct, from_unique_string) {
  int64_t resolve_timestamp = 1573196086 * 1e9;  // 2019-11-08 06:54:46

  auto product1 = CreateProductFromUniqueString("Spot:Huobi:BTC-USDT", resolve_timestamp);
  EXPECT_EQ(product1->base().currency(), "BTC");
  EXPECT_EQ(product1->quote().currency(), "USDT");
  EXPECT_EQ(product1->market(), MarketType::Spot);

  auto product2 = CreateProductFromUniqueString("Futures:Huobi:BTC-USD.QUARTER", resolve_timestamp);
  EXPECT_EQ(product2->base().currency(), "BTC");
  EXPECT_EQ(product2->quote().currency(), "USD");
  EXPECT_EQ(product2->market(), MarketType::Futures);
}

TEST(IProduct, create_all_products) {
  // A list of exchanges whose symbology has been implemented. This list needs
  // to be updated whenever new mea is added.
  std::set<MarketExchangeApi> mea_whitelist = {
      MarketExchangeApi {Spot, Binance, "v1"},
      MarketExchangeApi {Spot, Huobi, "v1"},
      MarketExchangeApi {Futures, Binance, "v1"},
      MarketExchangeApi {Futures, Huobi, "v1"},
      MarketExchangeApi {Futures, Okex, "v3"},
      MarketExchangeApi {Futures, Bitmex, "v1"},
      MarketExchangeApi {Spot, Okex, "v3"},
      MarketExchangeApi {Futures, Okex, "v3-swap"},
      MarketExchangeApi {Spot, Kraken, "v1"},
      MarketExchangeApi {Futures, Huobi, "v1-swap"}};

  int64_t ts = GetCurrentTimestamp();
  const auto data = toml::parse("data/coin2/feed/symbol_groups.toml");
  auto config = toml::get<
      std::unordered_map<std::string, std::unordered_map<std::string, std::vector<std::string>>>>(
      data);

  for (auto& exchange : config) {
    auto mea = MarketExchangeApi::FromSnakeString(exchange.first);
    if (mea_whitelist.find(mea) != mea_whitelist.end()) {
      for (auto it : exchange.second) {
        for (auto norm_symbol : it.second) {
          CreateProductFromNormString(mea, norm_symbol, ts);
        }
      }
    }
  }
}
